package com.jinke.api.modules.app.controller;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jinke.api.common.api.CommonPage;
import com.jinke.api.common.api.CommonResult;
import com.jinke.api.component.OpenAI;
import com.jinke.api.modules.app.enums.ValidateStatus;
import com.jinke.api.modules.app.model.Order;
import com.jinke.api.modules.app.model.SysCity;
import com.jinke.api.modules.app.model.SysState;
import com.jinke.api.modules.app.model.UserAddress;
import com.jinke.api.modules.app.request.AddressQueryRequest;
import com.jinke.api.modules.app.request.FormatAddrRequest;
import com.jinke.api.modules.app.request.GetCityRequest;
import com.jinke.api.modules.app.request.OrderCancelRequest;
import com.jinke.api.modules.app.response.GetCityResponse;
import com.jinke.api.modules.app.response.UserAddressExport;
import com.jinke.api.modules.app.service.OrderService;
import com.jinke.api.modules.app.service.SysCityService;
import com.jinke.api.modules.app.service.SysStateService;
import com.jinke.api.modules.app.service.UserAddressService;
import com.jinke.api.modules.third.ezeeship.model.request.EstimateRateRequest;
import com.jinke.api.modules.third.ezeeship.model.response.ValidateResponse;
import com.jinke.api.modules.third.ezeeship.service.EzeeShipService;
import com.jinke.api.modules.ums.model.UmsAdmin;
import com.jinke.api.security.util.AdminUserUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.dreamlu.mica.core.utils.BeanUtil;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

/**
 * <p>
 * 承运商平台 前端控制器
 * </p>
 *
 * @author macro
 * @since 2024-01-24
 */
@RestController
@RequestMapping("/app/user/address")
@Api(value = "用户地址管理", tags = "用户地址管理")
public class UserAddressController {

    @Resource
    UserAddressService userAddressService;
    @Autowired
    private SysStateService sysStateService;
    @Autowired
    private SysCityService sysCityService;
    @Autowired
    private EzeeShipService ezeeShipService;
    @Autowired
    private OrderService orderService;
    @Resource
    private Executor ezeeShipThreadPool;
    @Resource
    private StaticController staticController;

    @Resource
    private OpenAI openAI;

    @ApiOperation("添加地址")
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult create(@RequestBody UserAddress userAddress) {
        userAddress.setUserId(AdminUserUtil.getUserId());
        userAddress.setId(null);
        boolean success = userAddressService.save(userAddress);
        if (success) {
            return CommonResult.success(null);
        } else {
            return CommonResult.failed();
        }
    }

    @ApiOperation("校验地址")
    @RequestMapping(value = "/validate/batch", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult validateBatch(@RequestBody OrderCancelRequest request) {
        List<String> orderIds = request.getOrderIds();
        if (CollectionUtil.isEmpty(orderIds)) {
            return CommonResult.success();
        }
        UmsAdmin userInfo = AdminUserUtil.getUserInfo();
        Integer userId = userInfo.getId();
        // 管理员看所有数据

        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<Order>()
                .in(Order::getId, orderIds);
        if (!userInfo.isAdmin()) {
            queryWrapper.eq(Order::getUserId, userId);
        }
        List<Order> orders = orderService.list(queryWrapper
        );
        if (CollectionUtil.isEmpty(orders)) {
            return CommonResult.success();
        }

        final CountDownLatch countDownLatch = new CountDownLatch(orders.size());
        List<Order> updateOrders = new ArrayList<>();
        for (Order order : orders) {
            ezeeShipThreadPool.execute(() -> {
                try {
                    EstimateRateRequest.Address to = getAddress(order);

                    CommonResult validate = ezeeShipService.validate(to);
                    if (validate.isSucess()) {
                        Object data = validate.getData();
                        if (data instanceof ValidateResponse.TrackingData) {
                            Boolean isResidential = ((ValidateResponse.TrackingData) data).getIsResidential();
                            Order updateOrder = new Order();
                            updateOrder.setId(order.getId());
                            if (isResidential) {
                                updateOrder.setValidateStatus(ValidateStatus.RESIDENTIAL);
                            } else {
                                updateOrder.setValidateStatus(ValidateStatus.UN_RESIDENTIAL);
                            }
                            updateOrders.add(updateOrder);
                        }


                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    countDownLatch.countDown();
                }
            });

        }

        try {
            // 等待这个批次的所有任务完成
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        orderService.updateBatchById(updateOrders);

        return CommonResult.success();
    }

    @NotNull
    private static EstimateRateRequest.Address getAddress(Order order) {
        EstimateRateRequest.Address to = new EstimateRateRequest.Address();
        to.setCity(order.getToCity());
        to.setEmail(order.getToEmail());
        to.setCompany(order.getToCompany());
        to.setPhone(order.getToPhone());
        to.setAddressLine1(order.getToAddressLine1());
        to.setAddressLine2(order.getToAddressLine2());
        to.setCountryCode(order.getToCountryCode());
        to.setZipCode(order.getToZipCode());
        to.setPersonName(order.getToPersonName());
        to.setStateCode(order.getToStateCode());
        return to;
    }

    @ApiOperation("校验地址")
    @RequestMapping(value = "/validate", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult validate(@RequestBody UserAddress userAddress) {
        userAddress.setUserId(AdminUserUtil.getUserId());
        userAddress.setId(null);
        return ezeeShipService.validate(userAddress);
    }

    @ApiOperation(value = "修改地址", notes = "仅允许修改当前登录用户的地址")
    @RequestMapping(value = "/update/{id}", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult update(@PathVariable Integer id,
                               @RequestBody UserAddress userAddress) {
        userAddress.setId(id);
        LambdaUpdateWrapper<UserAddress> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(UserAddress::getId, id);
        updateWrapper.eq(UserAddress::getUserId, AdminUserUtil.getUserId());
        boolean success = userAddressService.update(userAddress, updateWrapper);
        if (success) {
            return CommonResult.success(null);
        } else {
            return CommonResult.failed();
        }
    }

    @ApiOperation("根据ID获取地址详情")
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<UserAddress> getItem(@PathVariable Integer id) {
        LambdaQueryWrapper<UserAddress> queryWrapper = (new LambdaQueryWrapper<UserAddress>()).
                eq(UserAddress::getId, id).
                eq(UserAddress::getUserId, AdminUserUtil.getUserId());
        UserAddress userAddress = userAddressService.getOne(queryWrapper);
        return CommonResult.success(userAddress);
    }

    @ApiOperation("根据ID删除地址")
    @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult delete(@PathVariable Integer id) {
        boolean success = userAddressService.remove((new LambdaQueryWrapper<UserAddress>())
                .eq(UserAddress::getId, id)
                .eq(UserAddress::getUserId, AdminUserUtil.getUserId())
        );
        if (success) {
            return CommonResult.success(null);
        } else {
            return CommonResult.failed();
        }
    }

    @ApiOperation("地址管理")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<CommonPage<UserAddress>> list(AddressQueryRequest request) {
        request.setUserId(AdminUserUtil.getUserId());
        Page<UserAddress> list = userAddressService.list(request);
        return CommonResult.success(CommonPage.restPage(list));
    }

    @ApiOperation("地址导出")
    @RequestMapping(value = "/down", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<String> down(AddressQueryRequest request) {
        request.setPageSize(999999);
        request.setPageNum(1);
        request.setUserId(AdminUserUtil.getUserId());
        Page<UserAddress> list = userAddressService.list(request);
        List<UserAddress> records = list.getRecords();
        if (CollectionUtil.isNotEmpty(records)) {

            List<UserAddressExport> balanceLogExports = records.stream().map(x -> {
                UserAddressExport userAddressExport = new UserAddressExport();
                BeanUtil.copy(x, userAddressExport);
                userAddressExport.setIsValid(BooleanUtil.isTrue(x.getIsValid()) ? "是" : "否");
                userAddressExport.setIsResidential(BooleanUtil.isTrue(x.getIsValid()) ? "是" : "否");
                return userAddressExport;

            }).collect(Collectors.toList());

            String s = staticController.exports(balanceLogExports, UserAddressExport.class);
            return CommonResult.success(s);
        }
        return CommonResult.success();
    }

    @ApiOperation("根据邮编获取州和城市")
    @RequestMapping(value = "/getCity", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<GetCityResponse> getCity(/*GetCityRequest request*/String zipCode) {
        //原来US逻辑要截取
        String tmpZipCode = null;
        //增加判断zipCode是否带有-校验
        if (StringUtils.isNotEmpty(zipCode)) {
            if (zipCode.contains("-")) {
                String[] split = zipCode.split("-");
                tmpZipCode = split[0];
            }else {
                tmpZipCode = zipCode;
            }
            SysCity sysCity = sysCityService.getOne(new LambdaQueryWrapper<SysCity>().eq(SysCity::getZipCode, tmpZipCode));
            if (sysCity != null) {
                Integer stateId = sysCity.getStateId();
                SysState sysState = sysStateService.getById(stateId);
                String stateCode = sysState.getStateCode();
                String countryCode = sysState.getCountryCode();

                GetCityResponse getCityResponse = new GetCityResponse();
                getCityResponse.setCity(sysCity.getCityName());
                getCityResponse.setStateCode(stateCode);
                getCityResponse.setCountryCode(countryCode);

                return CommonResult.success(getCityResponse);
            }else
            {
                //截取了查不到，再查一次全部的字段
                SysCity noSplitSysCity = sysCityService.getOne(new LambdaQueryWrapper<SysCity>().eq(SysCity::getZipCode, zipCode));
                if (noSplitSysCity != null) {
                    Integer stateId = noSplitSysCity.getStateId();
                    SysState sysState = sysStateService.getById(stateId);
                    String stateCode = sysState.getStateCode();
                    String countryCode = sysState.getCountryCode();
                    GetCityResponse getCityResponse = new GetCityResponse();
                    getCityResponse.setCity(noSplitSysCity.getCityName());
                    getCityResponse.setStateCode(stateCode);
                    getCityResponse.setCountryCode(countryCode);
                    return CommonResult.success(getCityResponse);
                }
                }
        }
        return CommonResult.success();
    }

    @ApiOperation("格式化")
    @RequestMapping(value = "/format", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<UserAddress> format(@RequestBody FormatAddrRequest formatAddrRequest) {
        UserAddress userAddress = new UserAddress();
        String content = openAI.asyncSend(formatAddrRequest.getAddr());
        if (StringUtils.isNotBlank(content)) {
            userAddress = JSONUtil.toBean(content, UserAddress.class);

            System.out.println();
        }
        return CommonResult.success(userAddress);
    }
}

